home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Node / NodeLibrary / HBBSNode.c < prev    next >
C/C++ Source or Header  |  1996-10-31  |  40KB  |  1,361 lines

  1. #define HBBSNODELIB
  2. #define MAIN
  3.  
  4. #include <ctype.h>
  5. #include <time.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #include <exec/exec.h>
  11. #include <exec/types.h>
  12.  
  13. #include <dos/dos.h>
  14. #include <dos/dostags.h>
  15.  
  16. #include <libraries/reqtools.h>
  17.  
  18. #include <intuition/intuition.h>
  19.  
  20. #include <devices/console.h>
  21. #include <devices/conunit.h>
  22.  
  23. #include <devices/serial.h>
  24. #include <hardware/cia.h>
  25.  
  26. #include <graphics/gfxbase.h>
  27. #include <graphics/scale.h>
  28.  
  29.  
  30. #include <clib/exec_protos.h>
  31. #include <clib/dos_protos.h>
  32. #include <clib/alib_protos.h>
  33. #include <clib/reqtools_protos.h>
  34. #include <clib/graphics_protos.h>
  35.  
  36. #include <pragmas/exec_pragmas.h>
  37. #include <pragmas/graphics_pragmas.h>
  38. #include <pragmas/dos_pragmas.h>
  39. #include <pragmas/reqtools.h>
  40.  
  41.  
  42. #include "//common/types.h"
  43. #include "//common/errors.h"
  44. #include "//common/defines.h"
  45. #include "//common/structures.h"
  46. #include "//common/strings.h"
  47. #include "//common/files.h"
  48. #include "//common/access.h"
  49. #include "//common/release.h"
  50.  
  51. #include "//library/hbbscommon_protos.h"
  52. #include "//library/hbbscommon_pragmas.h"
  53.  
  54. #define ClrSignal(s)  SetSignal(0,s)
  55.  
  56. char *versionstr="$VER: HBBSNode.library "RELEASE_STR;
  57.  
  58.  
  59. // needed libs..
  60.  
  61. struct DosLibrary *DOSBase=NULL;
  62. struct GfxBase *GfxBase=NULL;
  63. struct ExecBase *SysBase=NULL;
  64. struct ReqToolsBase *ReqToolsBase=NULL;
  65. struct Library *HBBSCommonBase=NULL;
  66.  
  67. struct BBSGlobalData *BBSGlobal=NULL;
  68. struct NodeData *N_ND=NULL;
  69.  
  70. struct DoorData C_DOOR; // current door (if active of course!)
  71.  
  72. V_BOOL DoorOK=FALSE;
  73.  
  74. // * SOME FORWARD DEFINES..
  75.  
  76. LONG __asm __saveds LIBHBBS_TimeOnline( void );
  77. LONG __asm __saveds LIBHBBS_TimeLeft( void );
  78.  
  79. void DoorStatus(V_BIGNUM status)
  80. {
  81.   struct DoorActivityMsg *DMsg;
  82.  
  83.   // memory will be free'd by NODE program (if node is alive of course!)
  84.   if (DMsg=(struct DoorActivityMsg *)AllocVec(sizeof(struct DoorActivityMsg),MEMF_PUBLIC))
  85.   {
  86.     DMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  87.     DMsg->message.mn_ReplyPort=NULL;  // must set to null!
  88.     DMsg->message.mn_Length=sizeof(struct DoorActivityMsg);
  89.     DMsg->MsgType=mtype_DOORACTIVITY;
  90.     DMsg->Status=status;
  91.     SendMessage((struct Message*)DMsg,N_ND->PortName);
  92.   }
  93. }
  94.  
  95. BOOL SendStartDoorMsg( void )
  96. {
  97.   struct DoorActivityMsg *DMsg;
  98.   BOOL retval=FALSE;
  99.  
  100.   if (DMsg=AllocVec(sizeof(struct DoorActivityMsg ),MEMF_PUBLIC))
  101.   {
  102.     DMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  103.     DMsg->message.mn_ReplyPort=C_DOOR.ReplyPort;
  104.     DMsg->message.mn_Length=sizeof(struct DoorActivityMsg);
  105.     DMsg->MsgType=mtype_DOORACTIVITY;
  106.     DMsg->Status=1;
  107.     if (SendMessage((struct Message*)DMsg,N_ND->DoorStartPortName)) retval=TRUE;
  108.     FreeVec(DMsg);
  109.   }
  110.   return(retval);
  111. }
  112.  
  113.  
  114. BOOL __asm __saveds LIBHBBS_InitNode(register __d0 int N_NodeNum)
  115. {
  116.   SysBase = *(struct ExecBase **) 4L;
  117.   if (DOSBase = (struct DosLibrary *) OpenLibrary (DOSNAME, 0))
  118.   {
  119.     if (GfxBase = (struct GfxBase *) OpenLibrary (GRAPHICSNAME, 0))
  120.     {
  121.       if (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
  122.       {
  123.         if (HBBSCommonBase = OpenLibrary("HBBSCommon.library",0))
  124.         {
  125.           if (BBSGlobal=HBBS_GimmeBBS())
  126.           {
  127.             if (N_ND=HBBS_NodeDataPtr(N_NodeNum))
  128.             {
  129.               return(TRUE);
  130.             }
  131.           }
  132.         }
  133.       }
  134.     }
  135.   }
  136.   return(FALSE);
  137. }
  138.  
  139. void __asm __saveds LIBHBBS_CleanUpNode( void )
  140. {
  141.   if (HBBSCommonBase)
  142.   {
  143. //    if (N_ND) HBBS_ResetNodeData(N_ND); // reset node variables
  144.     CloseLibrary (HBBSCommonBase);
  145.   }
  146.   if (ReqToolsBase) CloseLibrary ((struct Library *)ReqToolsBase);
  147.   if (GfxBase) CloseLibrary ((struct Library *) GfxBase);
  148.   if (DOSBase) CloseLibrary ((struct Library *) DOSBase);
  149. }
  150.  
  151. BOOL __asm __saveds LIBHBBS_InitDoor( register __d0 int N_NodeNum, register __a0 char *name)
  152. {
  153.   if (LIBHBBS_InitNode(N_NodeNum))
  154.   {
  155.     C_DOOR.node.ln_Name=name;
  156.  
  157.     sprintf(C_DOOR.DoorPortName,"HBBS_Node%dDoorPort_%d",N_NodeNum,N_ND->DoorsRunning+1); // we increment door number below..
  158.  
  159.     if (C_DOOR.DoorPort=CreatePort(C_DOOR.DoorPortName,0)) // named port
  160.     {
  161.       if (C_DOOR.ReplyPort=CreateMsgPort()) // unnamed port
  162.       {
  163.         // these must be updated at the same time as we don't want another program referencing
  164.         // ActiveDoor AND the door list and it not being correct now do we ? :-)
  165.  
  166.         Forbid();
  167.         N_ND->ActiveDoor=&C_DOOR;
  168.         AddHead(N_ND->DoorList,(struct Node*)&C_DOOR);
  169.         N_ND->DoorsRunning++;
  170.         Permit();
  171.  
  172.         // tell the NODE the door is running OK (if the node does not get a door OK message)
  173.         // within 15 seconds then it timesout! (unlike /X which locks up!!)
  174.  
  175.         if (SendStartDoorMsg())
  176.         {
  177.           DoorStatus(DMSG_DOORSTARTED);
  178.           // set the internal library's flag (used when we close the door down to free mem!
  179.           DoorOK=TRUE;
  180.           return(TRUE);
  181.         }
  182.  
  183.       }
  184.       else DeletePort(C_DOOR.DoorPort);
  185.     }
  186.   }
  187.   return(FALSE);
  188. }
  189.  
  190. void __asm __saveds LIBHBBS_CleanUpDoor( void )
  191. {
  192.   if (DoorOK)
  193.   {
  194.     DeleteMsgPort(C_DOOR.ReplyPort); // unnnamed port
  195.     DeletePort(C_DOOR.DoorPort);     // named port
  196.     Forbid();
  197.     // remove ourself from the doorlist
  198.  
  199.     RemHead(N_ND->DoorList);
  200.  
  201.     N_ND->DoorsRunning--;
  202.  
  203.     // set the active door to the door that called us (if we were spawned by another door)
  204.     // if not, set activedoor to null
  205.  
  206.     if (N_ND->DoorList->lh_Head->ln_Succ) // more doors ?
  207.     {
  208.       N_ND->ActiveDoor=(struct DoorData *)N_ND->DoorList->lh_Head;
  209.     }
  210.     else N_ND->ActiveDoor=NULL;
  211.  
  212.     Permit();
  213.  
  214.  
  215.     // tell the node that we've finished!
  216.     DoorStatus(DMSG_DOORFINISHED);
  217.  
  218.   }
  219.   LIBHBBS_CleanUpNode();
  220. }
  221. void  __asm __saveds LIBConWriteData(register __a0 UBYTE *data,register __d0 ULONG length)
  222. {
  223.   if (N_ND->ConOK && data && length>=0)
  224.   {
  225.     N_ND->ConWrite->io_Command  = CMD_WRITE;
  226.     N_ND->ConWrite->io_Data     = data;
  227.     N_ND->ConWrite->io_Length   = length;
  228.  
  229.     DoIO((struct IORequest *)N_ND->ConWrite);
  230.   }
  231. }
  232.  
  233. void  __asm __saveds LIBConWriteStr(register __a0 UBYTE *data)
  234. {
  235.   if (N_ND->ConOK && data)
  236.   {
  237.     N_ND->ConWrite->io_Command  = CMD_WRITE;
  238.     N_ND->ConWrite->io_Data     = data;
  239.     N_ND->ConWrite->io_Length   = -1;
  240.  
  241.     DoIO((struct IORequest *)N_ND->ConWrite);
  242.   }
  243. }
  244.  
  245. void  __asm __saveds LIBAbortConRead( void )
  246. {
  247.   if (N_ND->ConWaiting)
  248.   {
  249.     if (!CheckIO((struct IORequest*)N_ND->ConRead))
  250.     {
  251.       AbortIO((struct IORequest*)N_ND->ConRead);
  252.       WaitIO((struct IORequest*)N_ND->ConRead);
  253.     }
  254.     N_ND->ConWaiting=FALSE;
  255.   }
  256. }
  257.  
  258. void  __asm __saveds LIBSendConReadData( void )
  259. {
  260.   if (N_ND->ConWaiting) LIBAbortConRead();
  261.   N_ND->ConRead->io_Command  = CMD_READ;
  262.   N_ND->ConRead->io_Data     = (APTR)N_ND->ConBuffer;
  263.   N_ND->ConRead->io_Length   = N_ND->ConBufferLen;
  264.  
  265.   ClrSignal(1L << N_ND->ConRPort->mp_SigBit);
  266.   SendIO((struct IORequest*)N_ND->ConRead);
  267.   N_ND->ConWaiting=TRUE;
  268. }
  269.  
  270. void  __asm __saveds LIBConReadData(register __d0 ULONG Length ) // make DAMN sure that length is NEVER more that the buffer size!
  271. {
  272.   if (N_ND->ConWaiting) LIBAbortConRead();
  273.   N_ND->ConRead->io_Command  = CMD_READ;
  274.   N_ND->ConRead->io_Data     = (APTR)N_ND->ConBuffer;
  275.   N_ND->ConRead->io_Length   = Length;
  276.  
  277.   ClrSignal(1L << N_ND->ConRPort->mp_SigBit);
  278.   SendIO((struct IORequest*)N_ND->ConRead);
  279.   N_ND->ConWaiting=TRUE;
  280. }
  281.  
  282. void  __asm __saveds LIBConWaitData( void )
  283. {
  284.   if (!N_ND->ConWaiting) LIBSendConReadData();
  285.   WaitIO((struct IORequest*)N_ND->ConRead);
  286.   N_ND->ConWaiting=FALSE;
  287.   N_ND->ConBytes=N_ND->ConRead->io_Actual;
  288. }
  289.  
  290. // aborts an iorequest that has been sent
  291.  
  292. void __asm __saveds LIBAbortSerRead( void )
  293. {
  294.   if (N_ND->SerWaiting)
  295.   {
  296.     if (!CheckIO((struct IORequest*)N_ND->SerRead))
  297.     {
  298.       AbortIO((struct IORequest*)N_ND->SerRead);
  299.     }
  300.     WaitIO((struct IORequest*)N_ND->SerRead); // to tidy up..
  301.     N_ND->SerWaiting=FALSE;
  302.   }
  303. }
  304.  
  305. // SendIO()'s a request to read 1 bye
  306.  
  307. void __asm __saveds LIBSendSerReadData( void )
  308. {
  309.   N_ND->SerRead->IOSer.io_Command  = CMD_READ;
  310.   N_ND->SerRead->IOSer.io_Data     = (APTR)N_ND->SerBuffer;
  311.   N_ND->SerRead->IOSer.io_Length   = 1;
  312.  
  313.   ClrSignal(1L << N_ND->SerPort->mp_SigBit);
  314.   SendIO((struct IORequest*)N_ND->SerRead);
  315.   N_ND->SerWaiting=TRUE;
  316. }
  317.  
  318. void __asm __saveds LIBSerWaitData( void )
  319. {
  320.   if (!N_ND->SerWaiting) LIBSendSerReadData();
  321.   WaitIO((struct IORequest*)N_ND->SerRead);
  322.   N_ND->SerBytes=N_ND->SerRead->IOSer.io_Actual;
  323.   N_ND->SerWaiting=FALSE;
  324. }
  325.  
  326. // SendIO()'s a request to read a block of data
  327.  
  328. void __asm __saveds LIBSendSerReadBlock(register __a0 UBYTE *data,register __d0 ULONG length )
  329. {
  330.   LIBAbortSerRead(); // *C* not sure about this one..  might slowdown throughput..
  331.  
  332.   N_ND->SerRead->IOSer.io_Command  = CMD_READ;
  333.   N_ND->SerRead->IOSer.io_Data     = (APTR)data;
  334.   N_ND->SerRead->IOSer.io_Length   = length;
  335.  
  336.   ClrSignal(1L << N_ND->SerPort->mp_SigBit);
  337.   SendIO((struct IORequest*)N_ND->SerRead);
  338.   N_ND->SerWaiting=TRUE;
  339. }
  340.  
  341. // DioIO()'s a request to read a block of data
  342.  
  343. void __asm __saveds LIBWaitSerReadBlock(register __a0 UBYTE *data,register __d0 ULONG length )
  344. {
  345.   LIBSendSerReadBlock(data,length);
  346.   LIBSerWaitData();
  347. }
  348.  
  349. // DoIO()'s a Query!
  350.  
  351. ULONG __asm __saveds LIBSerQueryData( void )
  352. {
  353.   N_ND->SerWrite->IOSer.io_Command  = SDCMD_QUERY;
  354.   DoIO((struct IORequest*)N_ND->SerWrite);
  355.   return(N_ND->SerWrite->IOSer.io_Actual);
  356. }
  357.  
  358. V_BOOL __asm __saveds LIBCarrierLost( void )
  359. {
  360.   if (N_ND->LoginType==LOGIN_REMOTE && !N_ND->NodeDevice.NullModemCable)
  361.   {
  362.     LIBSerQueryData();
  363.     return((N_ND->SerWrite->io_Status & 1L << CIAB_COMCD) ? (V_BOOL)TRUE : (V_BOOL)FALSE);
  364.   }
  365.   else return((V_BOOL)FALSE);
  366. }
  367.  
  368. // writes a block of data to the serial port, checking for a timeout
  369. // (specified in seconds,micros) and returns FALSE if a timeout occured before all
  370. // the data has been sent, or there was a memory error.
  371.  
  372. BOOL __asm __saveds LIBSerWriteDataWithTimeout(register __a0 UBYTE *data,register __d0 ULONG length,register __d1 ULONG Seconds,register __d2 ULONG Micros)
  373. {
  374.   BOOL retval=FALSE;
  375.   struct TimerData *TD;
  376.  
  377.   if (TD=SubmitTimer(N_ND->NodeTimer,Seconds,Micros))
  378.   {
  379.     if (data && length>0)
  380.     {
  381.       LIBAbortSerRead();
  382.       N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  383.       N_ND->SerWrite->IOSer.io_Data     = data;
  384.       N_ND->SerWrite->IOSer.io_Length   = length;
  385.  
  386.       SendIO((struct IORequest *)N_ND->SerWrite);
  387.  
  388.       // ok, wait for the timer or serial device to tell us sommat..
  389.       Wait (DEF_TIMERSIG | DEF_SERSIG);
  390.  
  391.       // ok sommat hapenned. lets check the timer..
  392.       if (CheckTimer(N_ND->NodeTimer,TD))
  393.       {
  394.         // yup, timeout occured, so abort the serial write request..
  395.         AbortIO((struct IORequest *)N_ND->SerWrite);
  396.         TD=NULL;
  397.       }
  398.       else
  399.       {
  400.         // timer not done yet, so it must be the serial port that finished..
  401.         retval=TRUE;
  402.       }
  403.       // and then tidy up..
  404.       WaitIO((struct IORequest *)N_ND->SerWrite);
  405.     }
  406.     if (TD) AbortTimer(N_ND->NodeTimer,TD);
  407.   }
  408.   return(retval);
  409. }
  410.  
  411. // writes a block of data to the serial port without checking for a timeout..
  412.  
  413. void __asm __saveds LIBSerWriteData(register __a0 UBYTE *data,register __d0 ULONG length)
  414. {
  415.   if (data && length>0)
  416.   {
  417.     LIBAbortSerRead();
  418.     N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  419.     N_ND->SerWrite->IOSer.io_Data     = data;
  420.     N_ND->SerWrite->IOSer.io_Length   = length;
  421.  
  422.     DoIO((struct IORequest *)N_ND->SerWrite);
  423.   }
  424. }
  425.  
  426. BOOL __asm __saveds LIBSerWriteStrWithTimeout(register __a0 UBYTE *str,register __d0 ULONG Seconds,register __d1 ULONG Micros)
  427. {
  428.   BOOL retval=FALSE;
  429.   struct TimerData *TD;
  430.  
  431.   if (TD=SubmitTimer(N_ND->NodeTimer,Seconds,Micros))
  432.   {
  433.     if (str && str[0])  // str valid pointer ? and does it contain data ??
  434.     {
  435.       LIBAbortSerRead();
  436.       N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  437.       N_ND->SerWrite->IOSer.io_Data     = str;
  438.       N_ND->SerWrite->IOSer.io_Length   = -1;
  439.  
  440.       ClrSignal(DEF_TIMERSIG | DEF_SERSIG);
  441.  
  442.       SendIO((struct IORequest *)N_ND->SerWrite);
  443.  
  444.       // ok, wait for the timer or serial device to tell us sommat..
  445.       Wait (DEF_TIMERSIG | DEF_SERSIG);
  446.  
  447.       // ok sommat hapenned. lets check the timer..
  448.       if (CheckTimer(N_ND->NodeTimer,TD))
  449.       {
  450.         TD=NULL;
  451.         // yup, timeout occured, so abort the serial write request..
  452.         AbortIO((struct IORequest *)N_ND->SerWrite);
  453.       }
  454.       else
  455.       {
  456.         // timer not done yet, so it must be the serial port that finished..
  457.         retval=TRUE;
  458.         // and then tidy up..
  459.       }
  460.       WaitIO((struct IORequest *)N_ND->SerWrite);
  461.     }
  462.     if (TD) AbortTimer(N_ND->NodeTimer,TD);
  463.   }
  464.   return(retval);
  465. }
  466.  
  467. // writes a string to the serial device..
  468.  
  469. void __asm __saveds LIBSerWriteStr(register __a0 UBYTE *str)
  470. {
  471.   if (str && str[0])   // str valid pointer ? and does it contain data ??
  472.   {
  473.     LIBAbortSerRead();
  474.     N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  475.     N_ND->SerWrite->IOSer.io_Data     = str;
  476.     N_ND->SerWrite->IOSer.io_Length   = -1;
  477.     // hehe LamiExpress sets io_Length to strlen(str).. LAME! ;-)
  478.     // if they read the docs they might see that setting io_Length to -1
  479.     // makes the device output the contents of io_Data until it encounters
  480.     // a null terminator! :-)
  481.  
  482.     DoIO((struct IORequest *)N_ND->SerWrite);
  483.   }
  484. }
  485.  
  486. // writes a char to the serial device..
  487.  
  488. void __asm __saveds LIBSerWriteChar(register __d0 UBYTE c)
  489. {
  490.   char ch=c;
  491.  
  492.   LIBAbortSerRead();
  493.   N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  494.   N_ND->SerWrite->IOSer.io_Data     = &ch;
  495.   N_ND->SerWrite->IOSer.io_Length   = 1;
  496.   DoIO((struct IORequest *)N_ND->SerWrite);
  497. }
  498.  
  499. void  __asm __saveds LIBPutText(register __a0 UBYTE *str)
  500. {
  501.   // generic routine for all string output, this determines wether or not
  502.   // to write to the console or serial ports..
  503.  
  504.   if (str && str[0])
  505.   {
  506.     if (N_ND->ConOK)
  507.     {
  508.       N_ND->ConWrite->io_Command  = CMD_WRITE;
  509.       N_ND->ConWrite->io_Data     = str;
  510.       N_ND->ConWrite->io_Length   = -1;
  511.       DoIO((struct IORequest *)N_ND->ConWrite);
  512.     }
  513.     if ((N_ND->LoginType==LOGIN_REMOTE) && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL)))
  514.     {
  515.       LIBAbortSerRead();
  516.       N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  517.       N_ND->SerWrite->IOSer.io_Data     = str;
  518.       N_ND->SerWrite->IOSer.io_Length   = -1;
  519.       DoIO((struct IORequest *)N_ND->SerWrite);
  520.     }
  521.   }
  522. }
  523.  
  524. void  __asm __saveds LIBPutData(register __a0 UBYTE *data,register __d0 ULONG Length)
  525. {
  526.   // generic routine for all tring output, this determines wether or not
  527.   // to write to the console or serial ports..
  528.  
  529.   if (N_ND->ConOK) LIBConWriteData(data,Length);
  530.   if ((N_ND->LoginType==LOGIN_REMOTE)  && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL))) LIBSerWriteData(data,Length);
  531. }
  532.  
  533. void  __asm __saveds LIBPutChar(register __d0 UBYTE ch)
  534. {
  535.   char c=ch;
  536.   // generic routine for all tring output, this determines wether or not
  537.   // to write to the console or serial ports..
  538.   if (N_ND->ConOK) LIBConWriteData(&c,1);
  539.   if ((N_ND->LoginType==LOGIN_REMOTE) && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL))) LIBSerWriteData(&c,1);
  540. }
  541.  
  542. void  __asm __saveds LIBPutConText(register __a0 UBYTE *str)
  543. {
  544.   // generic routine for all tring output, this determines wether or not
  545.   // to write to the console or serial ports..
  546.  
  547.   if (N_ND->ConOK) LIBConWriteStr(str);
  548. }
  549.  
  550. void  __asm __saveds LIBPutConData(register __a0 UBYTE *data,register __d0 ULONG Length)
  551. {
  552.   // generic routine for all tring output, this determines wether or not
  553.   // to write to the console or serial ports..
  554.  
  555.   if (N_ND->ConOK) LIBConWriteData(data,Length);
  556. }
  557.  
  558. void  __asm __saveds LIBPutConChar(register __d0 UBYTE ch)
  559. {
  560.   char c=ch;
  561.   // generic routine for all tring output, this determines wether or not
  562.   // to write to the console or serial ports..
  563.   if (N_ND->ConOK) LIBConWriteData(&c,1);
  564. }
  565.  
  566. ULONG __asm __saveds LIBSetupConSerSigs( void )
  567. {
  568.   N_ND->ConSig=0L;
  569.   N_ND->ConWinSig=0L;
  570.   if (N_ND->ConOK)
  571.   {
  572.     if (N_ND->ConWaiting) N_ND->ConSig=DEF_CONSIG;
  573.     N_ND->ConWinSig=DEF_CONWINSIG;
  574.   }
  575.  
  576.   // only check serial if remote login.. OR if no-one's connected yet..
  577.  
  578.   if (N_ND->LoginType !=LOGIN_LOCAL && N_ND->SerOK && N_ND->SerWaiting)
  579.     N_ND->SerSig=DEF_SERSIG;
  580.   else
  581.     N_ND->SerSig=0;
  582.  
  583.   return(N_ND->SerSig | N_ND->ConSig);
  584. }
  585.  
  586. ULONG __asm __saveds LIBHandleConSigs(register __d0 ULONG ReturnedSigs)
  587. {
  588.   // a calling routine should call this until it returns false
  589.   // this is cos you might get two signals at the same time
  590.   // and you don't want to miss anything!
  591.  
  592.   if (ReturnedSigs & N_ND->ConSig && N_ND->ConOK && N_ND->ConWaiting)
  593.   {
  594.     LIBConWaitData();
  595.     N_ND->IBuffer=N_ND->ConBuffer;
  596.     N_ND->IBytes=N_ND->ConBytes;
  597.     return(TRUE);
  598.   }
  599.   return(FALSE);
  600. }
  601.  
  602. ULONG __asm __saveds LIBHandleSerSigs(register __d0 ULONG ReturnedSigs)
  603. {
  604.   // a calling routine should call this until it returns false
  605.   // this is cos you might get two signals at the same time
  606.   // and you don't want to miss anything!
  607.  
  608.  
  609.   if (ReturnedSigs & N_ND->SerSig && N_ND->SerOK && N_ND->SerWaiting)
  610.   {
  611.     LIBSerWaitData();
  612.     N_ND->IBuffer=N_ND->SerBuffer;
  613.     N_ND->IBytes=N_ND->SerBytes;
  614.     return(TRUE);
  615.   }
  616.   return(FALSE);
  617. }
  618.  
  619. ULONG __asm __saveds LIBHandleConSerSigs(register __d0 ULONG ReturnedSigs)
  620. {
  621.   // a calling routine should call this until it returns false
  622.   // this is cos you might get two signals at the same time
  623.   // and you don't want to miss anything!
  624.  
  625.   if (LIBHandleConSigs(ReturnedSigs) || LIBHandleSerSigs(ReturnedSigs))
  626.   {
  627.     return(TRUE);
  628.   }
  629.   else return(FALSE);
  630.  
  631. /*  if (ReturnedSigs & N_ND->ConSig && N_ND->ConOK && N_ND->ConWaiting)
  632.   {
  633.     LIBConWaitData();
  634.     N_ND->IBuffer=N_ND->ConBuffer;
  635.     N_ND->IBytes=N_ND->ConBytes;
  636.     return(TRUE);
  637.   }
  638.  
  639.   if (ReturnedSigs & N_ND->SerSig && N_ND->SerOK && N_ND->SerWaiting)
  640.   {
  641.     LIBSerWaitData();
  642.     N_ND->IBuffer=N_ND->SerBuffer;
  643.     N_ND->IBytes=N_ND->SerBytes;
  644.     return(TRUE);
  645.   }
  646.   return(FALSE);
  647. */
  648. }
  649.  
  650. ULONG SendDoorIOMessage(ULONG Status,UBYTE *Data,ULONG DataLength,ULONG Flags,UBYTE *OptionStr,ULONG Num1,ULONG Num2)
  651. {
  652.   ULONG retval=0;
  653.   struct DoorIOMsg *NewIOMsg=NULL;
  654.   if (NewIOMsg=(struct DoorIOMsg*)AllocVec(sizeof(struct DoorIOMsg),MEMF_PUBLIC))
  655.   {
  656.     NewIOMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  657.     NewIOMsg->message.mn_ReplyPort=C_DOOR.ReplyPort;
  658.     NewIOMsg->message.mn_Length=sizeof(struct DoorIOMsg);
  659.     NewIOMsg->MsgType=mtype_DOORIO;
  660.     NewIOMsg->Status=Status;
  661.     NewIOMsg->Data=Data;
  662.     NewIOMsg->DataLength=DataLength;
  663.     NewIOMsg->ReturnVal=0;
  664.     NewIOMsg->Flags=Flags;
  665.     NewIOMsg->OptionStr=OptionStr;
  666.     NewIOMsg->Num1=Num1;
  667.     NewIOMsg->Num2=Num2;
  668.     SendMessage((struct Message*)NewIOMsg,N_ND->PortName);
  669.     retval=NewIOMsg->ReturnVal;
  670.     FreeVec(NewIOMsg);
  671.   }
  672.   return(retval);
  673. }
  674.  
  675. ULONG QuickDoorIOMessage(ULONG Status,UBYTE *Data)
  676. {
  677.   // optimized send message for stuff that only uses Data and Datalen
  678.  
  679. //  return(SendDoorIOMessage(Status,Data,0,0,NULL,0,0));
  680.  
  681.   ULONG retval=0;
  682.   struct DoorIOMsg *NewIOMsg;
  683.   if (NewIOMsg=(struct DoorIOMsg*)AllocVec(sizeof(struct DoorIOMsg),MEMF_PUBLIC|MEMF_CLEAR))
  684.   {
  685.     NewIOMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  686.     NewIOMsg->message.mn_ReplyPort=C_DOOR.ReplyPort;
  687.     NewIOMsg->message.mn_Length=sizeof(struct DoorIOMsg);
  688.     NewIOMsg->MsgType=mtype_DOORIO;
  689.     NewIOMsg->Status=Status;
  690.     NewIOMsg->Data=Data;
  691.  
  692.     PutMsg(N_ND->NodePort,(struct Message*)NewIOMsg);
  693.  
  694.     if (1L << C_DOOR.ReplyPort->mp_SigBit==Wait(1L << C_DOOR.ReplyPort->mp_SigBit))
  695.     {
  696.       GetMsg(NewIOMsg->message.mn_ReplyPort);
  697.       retval=NewIOMsg->ReturnVal;
  698.     }
  699.     else retval=1L;
  700.  
  701.     FreeVec(NewIOMsg);
  702.     return(retval);
  703.  
  704.   }
  705.   else return(0);
  706. }
  707.  
  708. void __asm __saveds LIBDOOR_SysopText(register __a0 UBYTE *str)
  709. {
  710.   QuickDoorIOMessage(DOORIO_WRITECONSTR,str);
  711. }
  712.  
  713. void __asm __saveds LIBDOOR_WriteText(register __a0 UBYTE *str)
  714. {
  715.   QuickDoorIOMessage(DOORIO_WRITESTR,str);
  716. }
  717.  
  718. void __asm __saveds LIBDOOR_WriteSerText(register __a0 UBYTE *str)
  719. {
  720.   QuickDoorIOMessage(DOORIO_WRITESERSTR,str);
  721. }
  722.  
  723. ULONG __asm __saveds LIBDOOR_GetLine(register __d0 ULONG Flags, register __d1 char PasswordChar,register __d2 ULONG MaxLen,register __d3 ULONG Timeout,register __a0 UBYTE *PromptStr)
  724. {
  725.   char c=PasswordChar;
  726.  
  727.   return(SendDoorIOMessage(DOORIO_GETLINE,&c,1,Flags,PromptStr,MaxLen,Timeout));
  728. }
  729.  
  730. void __asm __saveds LIBDOOR_UpdateNodeStatus(register __d0 ULONG What)
  731. {
  732.   UBYTE *str=NULL;
  733.   UWORD X=0,MaxLen;
  734.   switch(What)
  735.   {
  736.     case UPD_NAME:
  737.       if (N_ND->User.Valid) str=N_ND->User.NormalData.Handle;
  738.       X=4;
  739.       MaxLen=MAX_NAME_LEN;
  740.       break;
  741.     case UPD_GROUP:
  742.       if (N_ND->User.Valid) str=N_ND->User.NormalData.Group;
  743.       X=164;
  744.       MaxLen=MAX_GROUP_LEN;
  745.       break;
  746.     case UPD_ACTION:
  747.       str=N_ND->Action;
  748.       X=324;
  749.       MaxLen=MAX_ACTION_LEN;
  750.       break;
  751.     case UPD_CPSBAUD:
  752.       if (!N_ND->TransferringFile) str=N_ND->ConnectBaud; // *C* add cps here
  753.       X=556;
  754.       MaxLen=MAX_CPSBAUD_LEN;
  755.       break;
  756.     default:
  757.       return;
  758.   }
  759.   // ok, have we got an option ?
  760.   // and a string to print ?
  761.   // AND if the window open ?
  762.   if ((X) && (str) && (!N_ND->NodeSettings.Iconified))
  763.   {
  764.     SetAPen(N_ND->NodeWnd->RPort,0L); // 0=grey
  765.     SetBPen(N_ND->NodeWnd->RPort,0); // grey!
  766.     RectFill(N_ND->NodeWnd->RPort, X+N_ND->NodeWnd->BorderLeft,15+N_ND->NodeWnd->BorderTop,X+N_ND->NodeWnd->BorderLeft+(8*MaxLen),15+N_ND->NodeWnd->BorderTop+9);
  767.  
  768.     if ((What == UPD_NAME) && (N_ND->NodeFlags & NFLG_PAGED))
  769.     {
  770.       SetAPen(N_ND->NodeWnd->RPort,2L); // white!
  771.     }
  772.     else
  773.     {
  774.       SetAPen(N_ND->NodeWnd->RPort,1L); // black!
  775.     }
  776.     Move(N_ND->NodeWnd->RPort,1+X+N_ND->NodeWnd->BorderLeft,8+14+N_ND->NodeWnd->BorderTop);  // 8 for text height, 13 for placement
  777.     Text(N_ND->NodeWnd->RPort,str,(strlen(str)>MaxLen) ? MaxLen : strlen(str));
  778.   }
  779. }
  780.  
  781. // spawn another system door, e.g. "FRONTEND"
  782.  
  783. void __asm __saveds LIBDOOR_SystemDoor(register __a0 UBYTE *doorname,register __a1 UBYTE *options)
  784. {
  785.   SendDoorIOMessage(DOORIO_SYSTEMDOOR,doorname,0,0,options,0,0);
  786. }
  787.  
  788. // spawn another user door, e.g. "FR W"
  789.  
  790. V_BOOL __asm __saveds LIBDOOR_UserDoor(register __a0 UBYTE *doorname,register __a1 UBYTE *options)
  791. {
  792.   return(SendDoorIOMessage(DOORIO_USERDOOR,doorname,0,0,options,0,0));
  793. }
  794.  
  795. V_BOOL __asm __saveds LIBDOOR_HangUp( void )
  796. {
  797.   return(SendDoorIOMessage(DOORIO_HANGUP,NULL,0,0,NULL,0,0));
  798. }
  799.  
  800. void __asm __saveds LIBDOOR_Return( register __a0 UBYTE *returnstring )
  801. {
  802.   strNcpy(N_ND->DoorReturn,returnstring,LEN_MAXDOORRETURN);
  803. }
  804.  
  805. V_BOOL __asm __saveds LIBDOOR_DisplayScreen( register __a0 UBYTE *screenname )
  806. {
  807.   return(SendDoorIOMessage(DOORIO_DISPLAYSCREEN,screenname,0,0,NULL,0,0));
  808. }
  809.  
  810. V_BOOL __asm __saveds LIBDOOR_DisplaySpecialScreen( register __a0 UBYTE *screenname )
  811. {
  812.   return(SendDoorIOMessage(DOORIO_DISPLAYSPECIALSCREEN,screenname,0,0,NULL,0,0));
  813. }
  814.  
  815.  
  816. V_BOOL __asm __saveds LIBDOOR_PausePrompt( register __a0 UBYTE *prompt )
  817. {
  818.   return(QuickDoorIOMessage(DOORIO_PAUSEPROMPT,prompt));
  819. }
  820.  
  821. void __asm __saveds LIBDOOR_Add_Last_Upload( register __a0 UBYTE *details )
  822. {
  823.   QuickDoorIOMessage(DOORIO_ADDLASTUPLOAD,details);
  824. }
  825.  
  826.  
  827.  
  828. V_BOOL __asm __saveds LIBDOOR_ContinuePrompt( register __a0 UBYTE *prompt,register __d0 V_BIGNUM Flags )
  829. {
  830.   return(SendDoorIOMessage(DOORIO_CONTINUEPROMPT,prompt,0,Flags,NULL,0,0));
  831. }
  832.  
  833.  
  834. void __asm __saveds LIBDOOR_MenuPrompt(register __a0 char *promptstr,register __d0 char promptdefault)
  835. {
  836.   char options[2];
  837.   options[0]=promptdefault;
  838.   options[1]=0;
  839.  
  840.   SendDoorIOMessage(DOORIO_MENUPROMPT,promptstr,0,0,options,0,0);
  841. }
  842.  
  843. void __asm __saveds LIBDOOR_Continue( register __d0 V_BOOL Continue )
  844. {
  845.   N_ND->DoorContinue=Continue;
  846. }
  847.  
  848. V_BOOL __asm __saveds LIBValidConfNum(register __d0 V_BIGNUM ConfNum)
  849. {
  850.   // index from 1 (i.e. first conf = 1
  851.   return((V_BOOL)((ConfNum>0 && ConfNum <=BBSGlobal->Conferences) ? TRUE : FALSE));
  852. }
  853.  
  854. struct ConfData __asm __saveds *LIBFindConf( void )
  855. {
  856.   struct ConfData *Conf=NULL;
  857.   V_BIGNUM ConfNum;
  858.  
  859.  
  860.   if (N_ND->CurrentConf)
  861.   {
  862.     Conf=N_ND->CurrentConf;
  863.   }
  864.   else
  865.   {
  866.     if (N_ND->User.Valid)
  867.     {
  868.       if (ConfNum=N_ND->User.CallData.LastConf)
  869.       {
  870.         if (LIBValidConfNum(ConfNum))
  871.         {
  872.           Conf=(struct ConfData *)GetNode(BBSGlobal->ConfList,ConfNum-1);
  873.         }
  874.       }
  875.     }
  876.   }
  877.   return(Conf);
  878.  
  879. }
  880.  
  881.  
  882. void  __asm __saveds LIBLoadAccess( register __a0 char *filename, register __a1 struct AccessData *AD)
  883. {
  884.   struct CfgFileData *CfgFile;
  885.   V_BOOL acsdata;
  886.  
  887.   if (CfgFile=HBBS_LoadConfig(filename,LCFG_NONE))
  888.   {
  889.  
  890.     /* Main Options */
  891.  
  892.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_DLFILES,OPT_SINGLE))
  893.       AD->Data[ACS_DLFILES]=acsdata ? 'Y' : 'N';
  894.  
  895.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ULFILES,OPT_SINGLE))
  896.       AD->Data[ACS_ULFILES]=acsdata ? 'Y' : 'N';
  897.  
  898.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_SYSOPCOMMENT,OPT_SINGLE))
  899.       AD->Data[ACS_SYSOPCOMMENT]=acsdata ? 'Y' : 'N';
  900.  
  901.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_READMAIL,OPT_SINGLE))
  902.       AD->Data[ACS_READMAIL]=acsdata ? 'Y' : 'N';
  903.  
  904.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_WRITEMAIL,OPT_SINGLE))
  905.       AD->Data[ACS_WRITEMAIL]=acsdata ? 'Y' : 'N';
  906.  
  907.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_SCANMAIL,OPT_SINGLE))
  908.       AD->Data[ACS_SCANMAIL]=acsdata ? 'Y' : 'N';
  909.  
  910.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWSTATUS,OPT_SINGLE))
  911.       AD->Data[ACS_ALLOWSTATUS]=acsdata ? 'Y' : 'N';
  912.  
  913.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWEDIT,OPT_SINGLE))
  914.       AD->Data[ACS_ALLOWEDIT]=acsdata ? 'Y' : 'N';
  915.  
  916.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_SCANFILES,OPT_SINGLE))
  917.       AD->Data[ACS_SCANFILES]=acsdata ? 'Y' : 'N';
  918.  
  919.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWVIEW,OPT_SINGLE))
  920.       AD->Data[ACS_ALLOWVIEW]=acsdata ? 'Y' : 'N';
  921.  
  922.  
  923.     /* Mail Options */
  924.  
  925.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_DELETEMAIL,OPT_SINGLE))
  926.       AD->Data[ACS_DELETEMAIL]=acsdata ? 'Y' : 'N';
  927.  
  928.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_DELETEGROUP,OPT_SINGLE))
  929.       AD->Data[ACS_DELETEGROUP]=acsdata ? 'Y' : 'N';
  930.  
  931.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_DELETEANYONE,OPT_SINGLE))
  932.       AD->Data[ACS_DELETEANYONE]=acsdata ? 'Y' : 'N';
  933.  
  934.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWALL,OPT_SINGLE))
  935.       AD->Data[ACS_ALLOWALL]=acsdata ? 'Y' : 'N';
  936.  
  937.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWEVERYBODY,OPT_SINGLE))
  938.       AD->Data[ACS_ALLOWEVERYBODY]=acsdata ? 'Y' : 'N';
  939.  
  940.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWMULTIPLE,OPT_SINGLE))
  941.       AD->Data[ACS_ALLOWMULTIPLE]=acsdata ? 'Y' : 'N';
  942.  
  943.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ATTACHFILES,OPT_SINGLE))
  944.       AD->Data[ACS_ATTACHFILES]=acsdata ? 'Y' : 'N';
  945.  
  946.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWMULTIFILES,OPT_SINGLE))
  947.       AD->Data[ACS_ALLOWMULTIFILES]=acsdata ? 'Y' : 'N';
  948.  
  949.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWPRIVATEFILES,OPT_SINGLE))
  950.       AD->Data[ACS_ALLOWPRIVATEFILES]=acsdata ? 'Y' : 'N';
  951.  
  952.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWALLFILES,OPT_SINGLE))
  953.       AD->Data[ACS_ALLOWALLFILES]=acsdata ? 'Y' : 'N';
  954.  
  955.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_ALLOWEVERYONEFILES,OPT_SINGLE))
  956.       AD->Data[ACS_ALLOWEVERYONEFILES]=acsdata ? 'Y' : 'N';
  957.  
  958.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_AUTOEXPIREMSG,OPT_SINGLE))
  959.       AD->Data[ACS_AUTOEXPIREMSG]=acsdata ? 'Y' : 'N';
  960.  
  961.     /* W command settings */
  962.  
  963.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITHANDLE,OPT_SINGLE))
  964.       AD->Data[ACS_EDITHANDLE]=acsdata ? 'Y' : 'N';
  965.  
  966.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITREALNAME,OPT_SINGLE))
  967.       AD->Data[ACS_EDITREALNAME]=acsdata ? 'Y' : 'N';
  968.  
  969.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITPASSWORD,OPT_SINGLE))
  970.       AD->Data[ACS_EDITPASSWORD]=acsdata ? 'Y' : 'N';
  971.  
  972.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITGROUP,OPT_SINGLE))
  973.       AD->Data[ACS_EDITGROUP]=acsdata ? 'Y' : 'N';
  974.  
  975.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITLOCATION,OPT_SINGLE))
  976.       AD->Data[ACS_EDITLOCATION]=acsdata ? 'Y' : 'N';
  977.  
  978.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITCOUNTRY,OPT_SINGLE))
  979.       AD->Data[ACS_EDITCOUNTRY]=acsdata ? 'Y' : 'N';
  980.  
  981.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITCOMPUTER,OPT_SINGLE))
  982.       AD->Data[ACS_EDITCOMPUTER]=acsdata ? 'Y' : 'N';
  983.  
  984.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITPHONENUMBER,OPT_SINGLE))
  985.       AD->Data[ACS_EDITPHONENUMBER]=acsdata ? 'Y' : 'N';
  986.  
  987.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITSCREENTYPE,OPT_SINGLE))
  988.       AD->Data[ACS_EDITSCREENTYPE]=acsdata ? 'Y' : 'N';
  989.  
  990.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITLINES,OPT_SINGLE))
  991.       AD->Data[ACS_EDITLINES]=acsdata ? 'Y' : 'N';
  992.  
  993.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITEDITOR,OPT_SINGLE))
  994.       AD->Data[ACS_EDITEDITOR]=acsdata ? 'Y' : 'N';
  995.  
  996.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_EDITPROTOCOL,OPT_SINGLE))
  997.       AD->Data[ACS_EDITPROTOCOL]=acsdata ? 'Y' : 'N';
  998.  
  999.     /* ULIMITEDxxxx Settings */
  1000.  
  1001.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_UNLIMTIME,OPT_SINGLE))
  1002.       AD->Data[ACS_UNLIMTIME]=acsdata ? 'Y' : 'N';
  1003.  
  1004.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_UNLIMCALLS,OPT_SINGLE))
  1005.       AD->Data[ACS_UNLIMCALLS]=acsdata ? 'Y' : 'N';
  1006.  
  1007.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_UNLIMBYTES,OPT_SINGLE))
  1008.       AD->Data[ACS_UNLIMBYTES]=acsdata ? 'Y' : 'N';
  1009.  
  1010.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_UNLIMCHAT,OPT_SINGLE))
  1011.       AD->Data[ACS_UNLIMCHAT]=acsdata ? 'Y' : 'N';
  1012.  
  1013.  
  1014.  
  1015. /*  Spare ones
  1016.  
  1017.  
  1018.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_,OPT_SINGLE))
  1019.       AD->Data[ACS_]=acsdata ? 'Y' : 'N';
  1020.  
  1021.     if (HBBS_GetSetting(CfgFile,(void *)&acsdata,VTYPE_BOOL,ACSSTR_,OPT_SINGLE))
  1022.       AD->Data[ACS_]=acsdata ? 'Y' : 'N';
  1023. */
  1024.     HBBS_FlushConfig(CfgFile);
  1025.   }
  1026.  
  1027. }
  1028.  
  1029. char __asm __saveds *LIBHBBS_ModifyString(register __a0 char *str)
  1030. {
  1031.   char tmpstr[20];  // *D* Document! the {x} codes
  1032.  
  1033.   // Time Left
  1034.  
  1035.   sprintf(tmpstr,"%d",LIBHBBS_TimeLeft());
  1036.   replace(str,str,"{L}",tmpstr);
  1037.  
  1038.   // Time Online
  1039.  
  1040.   sprintf(tmpstr,"%d",LIBHBBS_TimeOnline());
  1041.   replace(str,str,"{O}",tmpstr);
  1042.  
  1043.   // System Name
  1044.  
  1045.   replace(str,str,"{S}",BBSGlobal->BBSName);
  1046.  
  1047.   // Conference Name
  1048.  
  1049.   if (N_ND->CurrentConf) replace(str,str,"{C}",N_ND->CurrentConf->node.ln_Name);
  1050.  
  1051.   // Actual Time Without Seconds
  1052.  
  1053.   HBBS_GetTime(tmpstr);
  1054.   tmpstr[5]=0;
  1055.   replace(str,str,"{T}",tmpstr);
  1056.  
  1057.   // Actual Time WITH seconds
  1058.  
  1059.   HBBS_GetTime(tmpstr);
  1060.   replace(str,str,"{TS}",tmpstr);
  1061.  
  1062.   // Actual Date
  1063.  
  1064.   HBBS_GetDate(tmpstr);
  1065.   replace(str,str,"{D}",tmpstr);
  1066.  
  1067.   // Credits Left (In Current Conference)
  1068.  
  1069.   replace(str,str,"{B}","<Creds>");
  1070.  
  1071.   // Ansi CSI
  1072.  
  1073.   replace(str,str,"{E}","\033[");
  1074.  
  1075.  
  1076.   if (N_ND->User.Valid)
  1077.   {
  1078.  
  1079.     // Users Handle
  1080.  
  1081.     replace(str,str,"{H}",N_ND->User.CallData.Handle);
  1082.  
  1083.     // Users Group
  1084.  
  1085.     replace(str,str,"{G}",N_ND->User.CallData.Group);
  1086.   }
  1087.  
  1088.   return(str);
  1089. }
  1090.  
  1091. V_BOOL __asm __saveds LIBHBBS_LoadConfAcs( register __a0 struct ConfAcsData *ConfAcs, register __a1 char *filename)
  1092. {
  1093.   V_BOOL retval=FALSE,error=FALSE;
  1094.  
  1095.   struct CfgFileData *CfgFile;
  1096.   int loop;
  1097.   struct BoolNode *tmpnode;
  1098.   V_BOOL TmpVal;
  1099.   char tmpstr[BIG_STR];
  1100.  
  1101.   if (CfgFile=HBBS_LoadConfig(filename,LCFG_NONE))
  1102.   {
  1103.     if (HBBS_GetSetting(CfgFile,(void *)&ConfAcs->Name,VTYPE_STRING,"Name",OPT_SINGLE))
  1104.     {
  1105.       TmpVal=FALSE;
  1106.       HBBS_GetSetting(CfgFile,(void *)&TmpVal,VTYPE_BOOL,"Default",OPT_SINGLE);
  1107.  
  1108.       // set allow/disallow conf access to whatever "default" is set to for all conferences
  1109.       for (loop=0;!error && loop<BBSGlobal->Conferences;loop++)
  1110.       {
  1111.         tmpnode=(struct BoolNode*)GetNode(ConfAcs->Access,loop);
  1112.         tmpnode->Boolean=TmpVal;
  1113.       }
  1114.  
  1115.       // then make this value the opposite for all "Override_<confnum>=YES"'s
  1116.       for (loop=0;!error && loop<BBSGlobal->Conferences;loop++)
  1117.       {
  1118.         sprintf(tmpstr,"Override_%d",loop+1);
  1119.         if (HBBS_GetSetting(CfgFile,(void *)&TmpVal,VTYPE_BOOL,tmpstr,OPT_SINGLE) && TmpVal==TRUE)
  1120.         {
  1121.           tmpnode=(struct BoolNode*)GetNode(ConfAcs->Access,loop);
  1122.           tmpnode->Boolean=!tmpnode->Boolean;
  1123.         }
  1124.       }
  1125.  
  1126.       // then do the same thing for SeeDefault and all See_<confnum>'s
  1127.       TmpVal=FALSE;
  1128.       HBBS_GetSetting(CfgFile,(void *)&TmpVal,VTYPE_BOOL,"SeeDefault",OPT_SINGLE);
  1129.  
  1130.       for (loop=0;!error && loop<BBSGlobal->Conferences;loop++)
  1131.       {
  1132.         tmpnode=(struct BoolNode*)GetNode(ConfAcs->See,loop);
  1133.         tmpnode->Boolean=TmpVal;
  1134.       }
  1135.  
  1136.       for (loop=0;!error && loop<BBSGlobal->Conferences;loop++)
  1137.       {
  1138.         sprintf(tmpstr,"SeeOverride_%d",loop+1);
  1139.         if (HBBS_GetSetting(CfgFile,(void *)&TmpVal,VTYPE_BOOL,tmpstr,OPT_SINGLE) && TmpVal==TRUE)
  1140.         {
  1141.           tmpnode=(struct BoolNode*)GetNode(ConfAcs->See,loop);
  1142.           tmpnode->Boolean=!tmpnode->Boolean;
  1143.         }
  1144.       }
  1145.       retval=TRUE;
  1146.     }
  1147.     HBBS_FlushConfig(CfgFile);
  1148.   }
  1149.   return(retval);
  1150. }
  1151.  
  1152.  
  1153. void __asm __saveds LIBHBBS_SetAccess( void )
  1154. {
  1155.   char tmpfilename[BIG_STR];
  1156.   V_BIGNUM loop;
  1157.  
  1158.   // Clear out the access
  1159.  
  1160.   for (loop=0;loop<MAX_ACCESSSETTINGS;loop++)
  1161.   {
  1162.     N_ND->User.Acs.Data[loop]='N';
  1163.   }
  1164.  
  1165.   if (N_ND->User.Valid)
  1166.   {
  1167.     N_ND->User.Acs.AccessLevel=N_ND->User.CallData.Access;
  1168.  
  1169.     LIBLoadAccess("HBBS:Access/Levels/Level_Global",&N_ND->User.Acs);
  1170.  
  1171.     sprintf(tmpfilename,"HBBS:Access/Levels/Level_%d",N_ND->User.Acs.AccessLevel);
  1172.     LIBLoadAccess(tmpfilename,&N_ND->User.Acs);
  1173.  
  1174.     sprintf(tmpfilename,"%sAccess/Level_%d",N_ND->NodeLocation,N_ND->User.Acs.AccessLevel);
  1175.     LIBLoadAccess(tmpfilename,&N_ND->User.Acs);
  1176.  
  1177.     if (N_ND->CurrentConf)
  1178.     {
  1179.       sprintf(tmpfilename,"%sAccess/Level_%d",N_ND->CurrentConf->ConfPath,N_ND->User.Acs.AccessLevel);
  1180.       LIBLoadAccess(tmpfilename,&N_ND->User.Acs);
  1181.     }
  1182.  
  1183.     sprintf(tmpfilename,"HBBS:Access/Users/%s",N_ND->User.CallData.Handle);
  1184.     LIBLoadAccess(tmpfilename,&N_ND->User.Acs);
  1185.  
  1186.     sprintf(tmpfilename,"HBBS:System/Data/ConfAcs/%s.CFG",N_ND->User.CallData.ConfAcsDataFile);
  1187.     if (!LIBHBBS_LoadConfAcs(&N_ND->User.ConfAcs,tmpfilename))
  1188.     {
  1189.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_ERROR_OPENING,tmpfilename,TYPE_WARNING);
  1190.     }
  1191.   }
  1192. }
  1193.  
  1194. V_BOOL __asm __saveds LIBHBBS_CheckAccess(register __d0 ULONG AccessOption)
  1195. {
  1196.   if ((N_ND->User.Valid) && (N_ND->User.Acs.Data[AccessOption]=='Y')) return(TRUE); else return(FALSE);
  1197. }
  1198.  
  1199. void __asm __saveds LIBHBBS_AddToCallersLog(register __a0 UBYTE *String)
  1200. {
  1201.   UBYTE tmpstr[BIG_STR];
  1202.  
  1203.   if (N_ND->NodeSettings.CallersLogFile)
  1204.   {
  1205.  
  1206.     HBBS_GetDate(tmpstr);
  1207.     strcat(tmpstr," ");
  1208.     HBBS_GetTime(tmpstr+strlen(tmpstr));
  1209.     strcat(tmpstr," ");
  1210.     strcat(tmpstr,String);
  1211.     strcat(tmpstr,"\n");
  1212.  
  1213.     HBBS_AppendStrToFile(N_ND->NodeSettings.CallersLogFile,tmpstr);
  1214.   }
  1215. }
  1216.  
  1217.  
  1218. struct TaggedFile __asm __saveds *LIBHBBS_FindTag(register __a0 UBYTE *FileName,register __d0 BOOL MatchALL)
  1219. {
  1220.   struct TaggedFile *Tag=NULL,*retval=NULL;
  1221.  
  1222.   if (N_ND->TaggedFiles)
  1223.   {
  1224.     for (Tag=(struct TaggedFile*)N_ND->TaggedFileList->lh_Head;!retval && Tag->node.ln_Succ;Tag=(struct TaggedFile *)Tag->node.ln_Succ)
  1225.     {
  1226.       if (MatchALL)
  1227.       {
  1228.         if (stricmp(FileName,Tag->node.ln_Name)==0)
  1229.         {
  1230.           retval=Tag;
  1231.         }
  1232.       }
  1233.       else
  1234.       {
  1235.         if (stricmp(FilePart(FileName),FilePart(Tag->node.ln_Name))==0)
  1236.         {
  1237.           retval=Tag;
  1238.         }
  1239.       }
  1240.     }
  1241.   }
  1242.   return(retval);
  1243. }
  1244.  
  1245.  
  1246. void __asm __saveds LIBHBBS_SetBBSCols( void )
  1247. {
  1248.   struct CfgFileData *CfgFile;
  1249.   char filename[1024],*bbscolsfile="BBSColours.CFG";
  1250.  
  1251.   BOOL foundfile=FALSE;
  1252.   BYTE triedall=3;
  1253.  
  1254.   FreeAndSet(&N_ND->BBSCols->MenuTextANSI,"");
  1255.   FreeAndSet(&N_ND->BBSCols->MenuOpenBracket,"[");
  1256.   FreeAndSet(&N_ND->BBSCols->MenuCloseBracket,"]");
  1257.   FreeAndSet(&N_ND->BBSCols->MenuHighlightANSI,"");
  1258.   FreeAndSet(&N_ND->BBSCols->MenuDefaultOptANSI,"");
  1259.   FreeAndSet(&N_ND->BBSCols->MenuPromptANSI,":");
  1260.  
  1261.   do
  1262.   {
  1263.     triedall--;
  1264.     switch (triedall)
  1265.     {
  1266.       case 2:
  1267.         if (N_ND->CurrentConf)
  1268.         {
  1269.           strcpy(filename,N_ND->CurrentConf->ConfPath);
  1270.           strcat(filename,bbscolsfile);
  1271.         } else filename[0]=0;
  1272.         break;
  1273.       case 1:
  1274.         strcpy(filename,N_ND->NodeLocation);
  1275.         strcat(filename,bbscolsfile);
  1276.         break;
  1277.       case 0:
  1278.         strcpy(filename,"HBBS:System/Data/");
  1279.         strcat(filename,bbscolsfile);
  1280.         break;
  1281.     }
  1282.     if (filename[0])
  1283.     {
  1284.       if (CfgFile=HBBS_LoadConfig(filename,LCFG_NOSTRIPCOMMENTS))
  1285.       {
  1286.         foundfile=TRUE;
  1287.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuTextANSI,VTYPE_STRING,"MenuTextANSI",OPT_SINGLE)             ;
  1288.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuOpenBracket,VTYPE_STRING,"MenuOpenBracket",OPT_SINGLE)       ;
  1289.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuCloseBracket,VTYPE_STRING,"MenuCloseBracket",OPT_SINGLE)     ;
  1290.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuHighlightANSI,VTYPE_STRING,"MenuHighlightANSI",OPT_SINGLE)   ;
  1291.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuDefaultOptANSI,VTYPE_STRING,"MenuDefaultOptANSI",OPT_SINGLE) ;
  1292.         HBBS_GetSetting(CfgFile,(void *)&N_ND->BBSCols->MenuPromptANSI,VTYPE_STRING,"MenuPromptANSI",OPT_SINGLE)         ;
  1293.  
  1294.         HBBS_FlushConfig(CfgFile);
  1295.       }
  1296.     }
  1297.   } while ((!foundfile) && (triedall>0));
  1298. }
  1299.  
  1300.  
  1301. V_BOOL __asm __saveds LIBDOOR_CheckRaw(register __d0 ULONG Flags)
  1302. {
  1303.   return(SendDoorIOMessage(DOORIO_CHECKRAW,NULL,0,Flags,NULL,0,0));
  1304. }
  1305.  
  1306.  
  1307. LONG __asm __saveds LIBHBBS_TimeLeft( void )
  1308. {
  1309.   // return 0 if time limit is disabled, or the amount of time left..
  1310.   // therefore: only log people off if this returns <0, but ideally check for ACS_UNLIMTIME too...
  1311.   return((N_ND->User.Acs.Data[ACS_UNLIMTIME]=='Y') ? 0 : ((LONG)((N_ND->User.CallData.TimeAllowed+N_ND->User.CallData.ExtraTimeLimit)-N_ND->User.CallData.TimeUsed-LIBHBBS_TimeOnline())));
  1312.  
  1313. }
  1314.  
  1315. LONG __asm __saveds LIBHBBS_TimeOnline( void )
  1316. {
  1317.   LONG tdiff;
  1318.     // current time, - time logged on (secs) * 60 = mins on-line
  1319.   time(&tdiff);
  1320.  
  1321.   return((tdiff-N_ND->User.CallData.LastCalledDate) / 60);
  1322. }
  1323.  
  1324. void __asm __saveds LIBDOOR_Goodbye( void )
  1325. {
  1326.   // Perform all actions required for a sucessful logoff..
  1327.   // (see Logout door for an example..)
  1328.  
  1329.   N_ND->OnlineStatus=OS_OFFLINE;
  1330.  
  1331.   // lostcarrier flag is set by default when a user has a successful login,
  1332.   // so we must UNset it!
  1333.   N_ND->Actions[ACTN_CARRIERLOST]=ACTC_NONE;
  1334. }
  1335.  
  1336. BOOL __asm __saveds LIBHBBS_AllowConfAccess(register __d0 V_BIGNUM confnum)
  1337. {
  1338.   // confnum starts at 1.
  1339.  
  1340.   struct ConfData *tmpconf;
  1341.   struct BoolNode *boolnode;
  1342.  
  1343.   if (confnum>0 && confnum<=BBSGlobal->Conferences)
  1344.   {
  1345.     tmpconf=(struct ConfData *)GetNode(BBSGlobal->ConfList,confnum-1);
  1346.  
  1347.     // confaccess level higher than user's access level ?
  1348.  
  1349.     if (tmpconf->ConfAccess>N_ND->User.CallData.Access)
  1350.     {
  1351.       return(FALSE);
  1352.     }
  1353.     else
  1354.     {
  1355.       boolnode=(struct BoolNode *)GetNode(N_ND->User.ConfAcs.Access,confnum-1);
  1356.       return((BOOL)boolnode->Boolean);
  1357.     }
  1358.   }
  1359.   return(FALSE);
  1360. }
  1361.